#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
IR 属性节点定义
"""

import ast
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional, Iterator
from ..base import IRNode
from ...symbol_table import Symbol, SymbolKind
from ..expressions import build_expr_from_ast


@dataclass
class IRPropertyNode(IRNode):
    """IR属性节点"""

    name: str = field(default="")
    source_line: int = field(default=0)
    decorators: List[Dict[str, Any]] = field(default_factory=list)
    doc: str = field(default="")
    type_annotation: str = field(default="")
    default_value: Optional[Any] = field(default=None)
    access_modifier: str = field(default="public")  # "public", "private", "protected"
    is_static: bool = field(default=False)
    is_const: bool = field(default=False)
    is_reference: bool = field(default=False)
    # 关联的赋值语句，用于类型推断
    associated_assignment: Optional["IRNode"] = field(default=None, repr=False)
    # 类属性
    node_type: str = "property"

    @property
    def is_field(self) -> bool:
        """是否为实例字段（非静态）"""
        return not self.is_static

    def new_symbol(self) -> "Symbol":
        """创建属性的符号"""
        return Symbol(self.name, SymbolKind.ATTRIBUTE, ir_node=self)

    def get_local_symbols(self) -> Iterator[Symbol]:
        """获取属性节点中定义的本地符号

        属性节点本身不定义符号，返回空迭代器

        Returns:
            空的符号迭代器
        """
        return iter(())

    def get_cpp_type(self):
        """获取属性的C++类型

        优先使用type_inference和parameter_analysis阶段推导并缓存的类型信息，
        确保代码生成阶段不进行类型推导。
        """

        # 优先使用参数分析优化后的类型
        if "optimized_cpp_type" in self.extension_params:
            result = self.extension_params["optimized_cpp_type"]
            return result

        # 回退到基础的C++类型
        if "cpp_type" in self.extension_params:
            result = self.extension_params["cpp_type"]
            return result

        # 如果没有缓存的C++类型，但有缓存的类型信息，进行转换
        cached_type = self.extension_params.get("inferred_type")
        if cached_type:
            # 这里应该在type_replacement阶段已经处理过，但作为后备
            try:
                from ...type_system import get_cpp_type

                cpp_type = get_cpp_type(cached_type)
                if cpp_type:
                    # 缓存转换结果避免重复转换
                    self.extension_params["cpp_type"] = cpp_type
                    return cpp_type
            except (ImportError, AttributeError) as e:
                pass

        # 最后回退到原始类型注解
        return self.type_annotation

    def build_from_ast(self, node: ast.AnnAssign) -> None:
        """从 AST 注解赋值节点构建 IR 属性节点内容

        Args:
            node: AST 注解赋值节点
        """
        super().build_from_ast(node)

        if not isinstance(node.target, ast.Name):
            raise ValueError("Only simple name targets are supported for properties")

        # 设置属性节点属性
        self.name = node.target.id
        self.type_annotation = ast.unparse(node.annotation) if node.annotation else ""

        # 处理默认值
        if node.value:
            # 检查是否为field()调用
            if (
                isinstance(node.value, ast.Call)
                and isinstance(node.value.func, ast.Name)
                and node.value.func.id == "field"
            ):
                # 提取field()调用中的default参数
                default_value = None
                for keyword in node.value.keywords:
                    if keyword.arg == "default":
                        default_value = build_expr_from_ast(keyword.value, self)
                        break
                self.default_value = default_value
            else:
                self.default_value = build_expr_from_ast(node.value, self)
